home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / FunctionWindow.c < prev    next >
Text File  |  1994-12-28  |  23KB  |  735 lines

  1. /* FunctionWindow.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "FunctionWindow.h"
  31. #include "MainWindowStuff.h"
  32. #include "FunctionObject.h"
  33. #include "TextEdit.h"
  34. #include "WindowDispatcher.h"
  35. #include "Memory.h"
  36. #include "GrowIcon.h"
  37. #include "DataMunging.h"
  38. #include "Main.h"
  39. #include "DisassemblyWindow.h"
  40. #include "Alert.h"
  41. #include "FunctionList.h"
  42. #include "FindDialog.h"
  43. #include "GlobalWindowMenuList.h"
  44.  
  45.  
  46. #define WINSIZEX (400)
  47. #define WINSIZEY (300)
  48. #define TITLEINDENT (8)
  49.  
  50. #define NAMEX(W,H) (-1)
  51. #define NAMEY(W,H) (2)
  52. #define NAMEWIDTH(W,H) (W + 2)
  53. #define NAMEHEIGHT(W,H) (40)
  54.  
  55. #define BODYX(W,H) (NAMEX(W,H))
  56. #define BODYY(W,H) (NAMEY(W,H) + NAMEHEIGHT(W,H) + 4)
  57. #define BODYWIDTH(W,H) (NAMEWIDTH(W,H))
  58. #define BODYHEIGHT(W,H) (H - BODYY(W,H) + 1)
  59.  
  60.  
  61. struct FunctionWindowRec
  62.     {
  63.         MainWindowRec*            MainWindow;
  64.         FunctionObjectRec*    FunctionObject;
  65.         FunctionListRec*        FunctionList;
  66.  
  67.         WinType*                        ScreenID;
  68.         TextEditRec*                NameEdit;
  69.         TextEditRec*                BodyEdit;
  70.         TextEditRec*                ActiveTextEdit;
  71.         GenericWindowRec*        MyGenericWindow; /* how the window event dispatcher knows us */
  72.         MenuItemType*                MyMenuItem;
  73.     };
  74.  
  75.  
  76. FunctionWindowRec*    NewFunctionWindow(struct MainWindowRec* MainWindow,
  77.                                             struct FunctionObjectRec* FunctionObject,
  78.                                             struct FunctionListRec* FunctionList, OrdType WinX, OrdType WinY,
  79.                                             OrdType WinWidth, OrdType WinHeight)
  80.     {
  81.         FunctionWindowRec*    Window;
  82.         OrdType                            FontHeight;
  83.         char*                                StringTemp;
  84.  
  85.         /* deal with window placement */
  86.         if ((WinWidth < 100) || (WinHeight < 100) || ((eOptionKey & CheckModifiers()) != 0))
  87.             {
  88.                 WinX = 20 + WindowOtherEdgeWidths(eDocumentWindow);
  89.                 WinY = 20 + WindowTitleBarHeight(eDocumentWindow);
  90.                 WinWidth = WINSIZEX;
  91.                 WinHeight = WINSIZEY;
  92.             }
  93.         MakeWindowFitOnScreen(&WinX,&WinY,&WinWidth,&WinHeight);
  94.  
  95.         /* initialize existence of object */
  96.         Window = (FunctionWindowRec*)AllocPtrCanFail(
  97.             sizeof(FunctionWindowRec),"FunctionWindowRec");
  98.         if (Window == NIL)
  99.             {
  100.              FailurePoint1:
  101.                 return NIL;
  102.             }
  103.         Window->MainWindow = MainWindow;
  104.         Window->FunctionObject = FunctionObject;
  105.         Window->FunctionList = FunctionList;
  106.  
  107.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  108.             eWindowZoomable,eWindowResizable,WinX,WinY,WinWidth,WinHeight,
  109.             (void (*)(void*))&FunctionWindowUpdator,Window);
  110.         if (Window->ScreenID == 0)
  111.             {
  112.              FailurePoint2:
  113.                 ReleasePtr((char*)Window);
  114.                 goto FailurePoint1;
  115.             }
  116.         FontHeight = GetFontHeight(GetScreenFont(),9);
  117.  
  118.         Window->NameEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,GetScreenFont(),9,
  119.             NAMEX(WinWidth,WinHeight),NAMEY(WinWidth,WinHeight) + FontHeight,
  120.             NAMEWIDTH(WinWidth,WinHeight),NAMEHEIGHT(WinWidth,WinHeight) - FontHeight);
  121.         if (Window->NameEdit == NIL)
  122.             {
  123.              FailurePoint3:
  124.                 KillWindow(Window->ScreenID);
  125.                 goto FailurePoint2;
  126.             }
  127.         StringTemp = FunctionObjectGetNameCopy(FunctionObject);
  128.         if (StringTemp == NIL)
  129.             {
  130.              FailurePoint4:
  131.                 DisposeTextEdit(Window->NameEdit);
  132.                 goto FailurePoint3;
  133.             }
  134.         TextEditNewRawData(Window->NameEdit,StringTemp,"\x0a");
  135.         ReleasePtr(StringTemp);
  136.         TextEditHasBeenSaved(Window->NameEdit);
  137.  
  138.         Window->BodyEdit = NewTextEdit(Window->ScreenID,
  139.             (TEScrollType)(eTEVScrollBar | eTEHScrollBar),GetMonospacedFont(),9,
  140.             BODYX(WinWidth,WinHeight),BODYY(WinWidth,WinHeight) + FontHeight,
  141.             BODYWIDTH(WinWidth,WinHeight),BODYHEIGHT(WinWidth,WinHeight) - FontHeight);
  142.         if (Window->BodyEdit == NIL)
  143.             {
  144.              FailurePoint5:
  145.                 goto FailurePoint4;
  146.             }
  147.         StringTemp = FunctionObjectGetSourceCopy(FunctionObject);
  148.         if (StringTemp == NIL)
  149.             {
  150.              FailurePoint6:
  151.                 DisposeTextEdit(Window->BodyEdit);
  152.                 goto FailurePoint5;
  153.             }
  154.         SetTextEditTabSize(Window->BodyEdit,MainWindowGetTabSize(MainWindow));
  155.         TextEditNewRawData(Window->BodyEdit,StringTemp,"\x0a");
  156.         ReleasePtr(StringTemp);
  157.         TextEditHasBeenSaved(Window->BodyEdit);
  158.         SetTextEditAutoIndent(Window->BodyEdit,True);
  159.         Window->ActiveTextEdit = Window->BodyEdit;
  160.  
  161.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  162.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&FunctionWindowDoIdle,
  163.             (void (*)(void*))&FunctionWindowBecomeActive,
  164.             (void (*)(void*))&FunctionWindowBecomeInactive,
  165.             (void (*)(void*))&FunctionWindowJustResized,
  166.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&FunctionWindowDoMouseDown,
  167.             (void (*)(unsigned char,ModifierFlags,void*))&FunctionWindowDoKeyDown,
  168.             (void (*)(void*))&FunctionWindowClose,
  169.             (void (*)(void*))&FunctionWindowMenuSetup,
  170.             (void (*)(void*,MenuItemType*))&FunctionWindowDoMenuCommand);
  171.         if (Window->MyGenericWindow == NIL)
  172.             {
  173.              FailurePoint7:
  174.                 goto FailurePoint6;
  175.             }
  176.  
  177.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
  178.         if (Window->MyMenuItem == NIL)
  179.             {
  180.              FailurePoint8:
  181.                 CheckOutDyingWindow(Window->MyGenericWindow);
  182.                 goto FailurePoint7;
  183.             }
  184.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  185.             Window->ScreenID))
  186.             {
  187.              FailurePoint9:
  188.                 KillMenuItem(Window->MyMenuItem);
  189.                 goto FailurePoint8;
  190.             }
  191.  
  192.         FunctionWindowResetTitlebar(Window);
  193.  
  194.         return Window;
  195.     }
  196.  
  197.  
  198. void                                DisposeFunctionWindow(FunctionWindowRec* Window)
  199.     {
  200.         CheckPtrExistence(Window);
  201.  
  202.         /* save data */
  203.         if (!FunctionWindowWritebackModifiedData(Window))
  204.             {
  205.                 /* failed -- now what? */
  206.             }
  207.  
  208.         DeregisterWindowMenuItem(Window->MyMenuItem);
  209.         KillMenuItem(Window->MyMenuItem);
  210.         CheckOutDyingWindow(Window->MyGenericWindow);
  211.         FunctionObjectClosingWindowNotify(Window->FunctionObject,
  212.             GetWindowXStart(Window->ScreenID),GetWindowYStart(Window->ScreenID),
  213.             GetWindowWidth(Window->ScreenID),GetWindowHeight(Window->ScreenID));
  214.         DisposeTextEdit(Window->NameEdit);
  215.         DisposeTextEdit(Window->BodyEdit);
  216.         KillWindow(Window->ScreenID);
  217.         ReleasePtr((char*)Window);
  218.     }
  219.  
  220.  
  221. void                                FunctionWindowDoIdle(FunctionWindowRec* Window,
  222.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  223.                                             ModifierFlags Modifiers)
  224.     {
  225.         CheckPtrExistence(Window);
  226.         TextEditUpdateCursor(Window->ActiveTextEdit);
  227.         if (CheckCursorFlag)
  228.             {
  229.                 if (TextEditIBeamTest(Window->NameEdit,XLoc,YLoc)
  230.                     || TextEditIBeamTest(Window->BodyEdit,XLoc,YLoc))
  231.                     {
  232.                         SetIBeamCursor();
  233.                     }
  234.                  else
  235.                     {
  236.                         SetArrowCursor();
  237.                     }
  238.             }
  239.     }
  240.  
  241.  
  242. void                                FunctionWindowBecomeActive(FunctionWindowRec* Window)
  243.     {
  244.         OrdType                        XSize;
  245.         OrdType                        YSize;
  246.  
  247.         CheckPtrExistence(Window);
  248.         EnableTextEditSelection(Window->ActiveTextEdit);
  249.         XSize = GetWindowWidth(Window->ScreenID);
  250.         YSize = GetWindowHeight(Window->ScreenID);
  251.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  252.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  253.     }
  254.  
  255.  
  256. void                                FunctionWindowBecomeInactive(FunctionWindowRec* Window)
  257.     {
  258.         OrdType                        XSize;
  259.         OrdType                        YSize;
  260.  
  261.         CheckPtrExistence(Window);
  262.         DisableTextEditSelection(Window->ActiveTextEdit);
  263.         XSize = GetWindowWidth(Window->ScreenID);
  264.         YSize = GetWindowHeight(Window->ScreenID);
  265.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  266.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  267.     }
  268.  
  269.  
  270. void                                FunctionWindowJustResized(FunctionWindowRec* Window)
  271.     {
  272.         OrdType                        XSize;
  273.         OrdType                        YSize;
  274.         OrdType                        FontHeight;
  275.  
  276.         CheckPtrExistence(Window);
  277.         XSize = GetWindowWidth(Window->ScreenID);
  278.         YSize = GetWindowHeight(Window->ScreenID);
  279.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  280.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  281.         FontHeight = GetFontHeight(GetScreenFont(),9);
  282.         SetTextEditPosition(Window->NameEdit,
  283.             NAMEX(XSize,YSize),NAMEY(XSize,YSize) + FontHeight,
  284.             NAMEWIDTH(XSize,YSize),NAMEHEIGHT(XSize,YSize) - FontHeight);
  285.         SetTextEditPosition(Window->BodyEdit,
  286.             BODYX(XSize,YSize),BODYY(XSize,YSize) + FontHeight,
  287.             BODYWIDTH(XSize,YSize),BODYHEIGHT(XSize,YSize) - FontHeight);
  288.     }
  289.  
  290.  
  291. void                                FunctionWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  292.                                             ModifierFlags Modifiers, FunctionWindowRec* Window)
  293.     {
  294.         CheckPtrExistence(Window);
  295.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  296.             && (XLoc < GetWindowWidth(Window->ScreenID))
  297.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  298.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  299.             {
  300.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  301.                 FunctionWindowJustResized(Window);
  302.             }
  303.         else if (TextEditHitTest(Window->NameEdit,XLoc,YLoc))
  304.             {
  305.                 if (Window->ActiveTextEdit != Window->NameEdit)
  306.                     {
  307.                         DisableTextEditSelection(Window->ActiveTextEdit);
  308.                         Window->ActiveTextEdit = Window->NameEdit;
  309.                         EnableTextEditSelection(Window->ActiveTextEdit);
  310.                     }
  311.                 TextEditDoMouseDown(Window->NameEdit,XLoc,YLoc,Modifiers);
  312.             }
  313.         else if (TextEditHitTest(Window->BodyEdit,XLoc,YLoc))
  314.             {
  315.                 if (Window->ActiveTextEdit != Window->BodyEdit)
  316.                     {
  317.                         DisableTextEditSelection(Window->ActiveTextEdit);
  318.                         Window->ActiveTextEdit = Window->BodyEdit;
  319.                         EnableTextEditSelection(Window->ActiveTextEdit);
  320.                     }
  321.                 TextEditDoMouseDown(Window->BodyEdit,XLoc,YLoc,Modifiers);
  322.             }
  323.     }
  324.  
  325.  
  326. void                                FunctionWindowDoKeyDown(unsigned char KeyCode,
  327.                                             ModifierFlags Modifiers,FunctionWindowRec* Window)
  328.     {
  329.         CheckPtrExistence(Window);
  330.         TextEditDoKeyPressed(Window->ActiveTextEdit,KeyCode,Modifiers);
  331.     }
  332.  
  333.  
  334. void                                FunctionWindowClose(FunctionWindowRec* Window)
  335.     {
  336.         DisposeFunctionWindow(Window);
  337.     }
  338.  
  339.  
  340. void                                FunctionWindowUpdator(FunctionWindowRec* Window)
  341.     {
  342.         OrdType                        XSize;
  343.         OrdType                        YSize;
  344.  
  345.         CheckPtrExistence(Window);
  346.         TextEditFullRedraw(Window->NameEdit);
  347.         TextEditFullRedraw(Window->BodyEdit);
  348.         XSize = GetWindowWidth(Window->ScreenID);
  349.         YSize = GetWindowHeight(Window->ScreenID);
  350.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  351.         DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Function Name:",14,
  352.             NAMEX(XSize,YSize) + TITLEINDENT,NAMEY(XSize,YSize),eBold);
  353.         DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Function Body:",14,
  354.             BODYX(XSize,YSize) + TITLEINDENT,BODYY(XSize,YSize),eBold);
  355.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  356.         DrawBitmap(Window->ScreenID,XSize - 15,YSize - 15,
  357.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  358.     }
  359.  
  360.  
  361. void                                FunctionWindowMenuSetup(FunctionWindowRec* Window)
  362.     {
  363.         CheckPtrExistence(Window);
  364.         MainWindowEnableGlobalMenus(Window->MainWindow);
  365.         EnableMenuItem(mPaste);
  366.         ChangeItemName(mPaste,"Paste Text");
  367.         if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  368.             {
  369.                 EnableMenuItem(mCut);
  370.                 ChangeItemName(mCut,"Cut Text");
  371.                 EnableMenuItem(mCopy);
  372.                 ChangeItemName(mCopy,"Copy Text");
  373.                 EnableMenuItem(mClear);
  374.                 ChangeItemName(mClear,"Clear Text");
  375.             }
  376.         EnableMenuItem(mShiftLeft);
  377.         EnableMenuItem(mShiftRight);
  378.         EnableMenuItem(mBalanceParens);
  379.         EnableMenuItem(mSelectAll);
  380.         ChangeItemName(mSelectAll,"Select All Text");
  381.         if (TextEditCanWeUndo(Window->ActiveTextEdit))
  382.             {
  383.                 EnableMenuItem(mUndo);
  384.                 ChangeItemName(mUndo,"Undo Text Change");
  385.             }
  386.         ChangeItemName(mCloseFile,"Close Function Editor");
  387.         EnableMenuItem(mCloseFile);
  388.         ChangeItemName(mBuildFunction,"Compile Function Module");
  389.         EnableMenuItem(mBuildFunction);
  390.         ChangeItemName(mUnbuildFunction,"Unbuild This Function Module");
  391.         EnableMenuItem(mUnbuildFunction);
  392.         ChangeItemName(mDisassembleFunction,"Disassemble Function Module");
  393.         EnableMenuItem(mDisassembleFunction);
  394.         ChangeItemName(mDeleteObject,"Delete Function");
  395.         EnableMenuItem(mDeleteObject);
  396.         EnableMenuItem(mFind);
  397.         if (PtrSize(GlobalSearchString) != 0)
  398.             {
  399.                 EnableMenuItem(mFindAgain);
  400.                 if ((Window->ActiveTextEdit != NIL)
  401.                     && TextEditIsThereValidSelection(Window->ActiveTextEdit))
  402.                     {
  403.                         EnableMenuItem(mReplace);
  404.                         EnableMenuItem(mReplaceAndFindAgain);
  405.                     }
  406.             }
  407.         EnableMenuItem(mShowSelection);
  408.         if ((Window->ActiveTextEdit != NIL)
  409.             && TextEditIsThereValidSelection(Window->ActiveTextEdit))
  410.             {
  411.                 EnableMenuItem(mEnterSelection);
  412.             }
  413.         SetItemCheckmark(Window->MyMenuItem);
  414.     }
  415.  
  416.  
  417. void                                FunctionWindowDoMenuCommand(FunctionWindowRec* Window,
  418.                                             MenuItemType* MenuItem)
  419.     {
  420.         CheckPtrExistence(Window);
  421.         if (MainWindowDoGlobalMenuItem(Window->MainWindow,MenuItem))
  422.             {
  423.             }
  424.         else if (MenuItem == mPaste)
  425.             {
  426.                 TextEditDoMenuPaste(Window->ActiveTextEdit);
  427.             }
  428.         else if (MenuItem == mCut)
  429.             {
  430.                 TextEditDoMenuCut(Window->ActiveTextEdit);
  431.             }
  432.         else if (MenuItem == mCopy)
  433.             {
  434.                 TextEditDoMenuCopy(Window->ActiveTextEdit);
  435.             }
  436.         else if (MenuItem == mClear)
  437.             {
  438.                 TextEditDoMenuClear(Window->ActiveTextEdit);
  439.             }
  440.         else if (MenuItem == mSelectAll)
  441.             {
  442.                 TextEditDoMenuSelectAll(Window->ActiveTextEdit);
  443.             }
  444.         else if (MenuItem == mUndo)
  445.             {
  446.                 TextEditDoMenuUndo(Window->ActiveTextEdit);
  447.             }
  448.         else if (MenuItem == mCloseFile)
  449.             {
  450.                 FunctionWindowClose(Window);
  451.             }
  452.         else if (MenuItem == mShiftLeft)
  453.             {
  454.                 TextEditShiftSelectionLeftOneTab(Window->ActiveTextEdit);
  455.             }
  456.         else if (MenuItem == mShiftRight)
  457.             {
  458.                 TextEditShiftSelectionRightOneTab(Window->ActiveTextEdit);
  459.             }
  460.         else if (MenuItem == mBalanceParens)
  461.             {
  462.                 TextEditBalanceParens(Window->ActiveTextEdit);
  463.             }
  464.         else if (MenuItem == mBuildFunction)
  465.             {
  466.                 FunctionObjectBuild(Window->FunctionObject);
  467.             }
  468.         else if (MenuItem == mUnbuildFunction)
  469.             {
  470.                 FunctionObjectUnbuild(Window->FunctionObject);
  471.             }
  472.         else if (MenuItem == mDisassembleFunction)
  473.             {
  474.                 char*                    Disassembly;
  475.  
  476.                 Disassembly = FunctionObjectDisassemble(Window->FunctionObject);
  477.                 if (Disassembly != NIL)
  478.                     {
  479.                         if (NewDisassemblyWindow(Disassembly,Window->MainWindow) == NIL)
  480.                             {
  481.                                 AlertHalt("There is not enough memory available to "
  482.                                     "show the disassembly window.",NIL);
  483.                             }
  484.                         ReleasePtr(Disassembly);
  485.                     }
  486.             }
  487.         else if (MenuItem == mDeleteObject)
  488.             {
  489.                 FunctionListDeleteFunction(Window->FunctionList,Window->FunctionObject);
  490.             }
  491.         else if (MenuItem == mFind)
  492.             {
  493.                 if (Window->ActiveTextEdit != Window->BodyEdit)
  494.                     {
  495.                         DisableTextEditSelection(Window->ActiveTextEdit);
  496.                         Window->ActiveTextEdit = Window->BodyEdit;
  497.                         EnableTextEditSelection(Window->ActiveTextEdit);
  498.                     }
  499.                 switch (DoFindDialog(&GlobalSearchString,&GlobalReplaceString,
  500.                     mCut,mPaste,mCopy,mUndo,mSelectAll,mClear))
  501.                     {
  502.                         default:
  503.                             EXECUTE(PRERR(ForceAbort,
  504.                                 "FunctionWindowDoMenuCommand:  bad value from DoFindDialog"));
  505.                             break;
  506.                         case eFindCancel:
  507.                         case eDontFind:
  508.                             break;
  509.                         case eFindFromStart:
  510.                             SetTextEditInsertionPoint(Window->ActiveTextEdit,0,0);
  511.                             TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  512.                             TextEditShowSelection(Window->ActiveTextEdit);
  513.                             break;
  514.                         case eFindAgain:
  515.                             TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  516.                             TextEditShowSelection(Window->ActiveTextEdit);
  517.                             break;
  518.                     }
  519.             }
  520.         else if (MenuItem == mFindAgain)
  521.             {
  522.                 if (Window->ActiveTextEdit != Window->BodyEdit)
  523.                     {
  524.                         DisableTextEditSelection(Window->ActiveTextEdit);
  525.                         Window->ActiveTextEdit = Window->BodyEdit;
  526.                         EnableTextEditSelection(Window->ActiveTextEdit);
  527.                     }
  528.                 TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  529.                 TextEditShowSelection(Window->ActiveTextEdit);
  530.             }
  531.         else if (MenuItem == mReplace)
  532.             {
  533.                 if (Window->ActiveTextEdit != Window->BodyEdit)
  534.                     {
  535.                         DisableTextEditSelection(Window->ActiveTextEdit);
  536.                         Window->ActiveTextEdit = Window->BodyEdit;
  537.                         EnableTextEditSelection(Window->ActiveTextEdit);
  538.                     }
  539.                 if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  540.                     {
  541.                         TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
  542.                             SYSTEMLINEFEED);
  543.                     }
  544.             }
  545.         else if (MenuItem == mReplaceAndFindAgain)
  546.             {
  547.                 if (Window->ActiveTextEdit != Window->BodyEdit)
  548.                     {
  549.                         DisableTextEditSelection(Window->ActiveTextEdit);
  550.                         Window->ActiveTextEdit = Window->BodyEdit;
  551.                         EnableTextEditSelection(Window->ActiveTextEdit);
  552.                     }
  553.                 if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
  554.                     {
  555.                         TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
  556.                             SYSTEMLINEFEED);
  557.                         TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
  558.                         TextEditShowSelection(Window->ActiveTextEdit);
  559.                     }
  560.             }
  561.         else if (MenuItem == mShowSelection)
  562.             {
  563.                 TextEditShowSelection(Window->ActiveTextEdit);
  564.             }
  565.         else if (MenuItem == mEnterSelection)
  566.             {
  567.                 char*                        NewString;
  568.  
  569.                 NewString = TextEditGetSelection(Window->ActiveTextEdit);
  570.                 if (NewString != NIL)
  571.                     {
  572.                         ReleasePtr(GlobalSearchString);
  573.                         GlobalSearchString = NewString;
  574.                     }
  575.             }
  576.         else
  577.             {
  578.                 EXECUTE(PRERR(AllowResume,"FunctionWindowDoMenuCommand:  unknown menu command"));
  579.             }
  580.     }
  581.  
  582.  
  583. /* utility routine to hilite a text line on which a compile error has occurred */
  584. void                                FunctionWindowHiliteLine(FunctionWindowRec* Window, long ErrorLine)
  585.     {
  586.         CheckPtrExistence(Window);
  587.         if (Window->ActiveTextEdit != Window->BodyEdit)
  588.             {
  589.                 DisableTextEditSelection(Window->ActiveTextEdit);
  590.                 Window->ActiveTextEdit = Window->BodyEdit;
  591.                 EnableTextEditSelection(Window->ActiveTextEdit);
  592.             }
  593.         SetTextEditSelection(Window->BodyEdit,ErrorLine,0,ErrorLine + 1,0);
  594.         TextEditShowSelection(Window->BodyEdit);
  595.     }
  596.  
  597.  
  598. /* utility routine to bring this window to the top. */
  599. void                                FunctionWindowBringToTop(FunctionWindowRec* Window)
  600.     {
  601.         CheckPtrExistence(Window);
  602.         ActivateThisWindow(Window->ScreenID);
  603.     }
  604.  
  605.  
  606. /* check to see if data in text edit boxes has been altered */
  607. MyBoolean                        HasFunctionWindowBeenModified(FunctionWindowRec* Window)
  608.     {
  609.         CheckPtrExistence(Window);
  610.         return TextEditDoesItNeedToBeSaved(Window->NameEdit)
  611.             || TextEditDoesItNeedToBeSaved(Window->BodyEdit);
  612.     }
  613.  
  614.  
  615. /* get a copy of the name edit */
  616. char*                                FunctionWindowGetNameCopy(FunctionWindowRec* Window)
  617.     {
  618.         CheckPtrExistence(Window);
  619.         return TextEditGetRawData(Window->NameEdit,"\x0a");
  620.     }
  621.  
  622.  
  623. /* get a copy of the source text edit */
  624. char*                                FunctionWindowGetSourceCopy(FunctionWindowRec* Window)
  625.     {
  626.         CheckPtrExistence(Window);
  627.         return TextEditGetRawData(Window->BodyEdit,"\x0a");
  628.     }
  629.  
  630.  
  631. /* the name of the document has changed, so change the name of the window */
  632. void                                FunctionWindowGlobalNameChange(FunctionWindowRec* Window,
  633.                                             char* NewFilename)
  634.     {
  635.         char*                            LocalNameCopy;
  636.  
  637.         CheckPtrExistence(Window);
  638.         CheckPtrExistence(NewFilename);
  639.         LocalNameCopy = FunctionWindowGetNameCopy(Window);
  640.         if (LocalNameCopy != NIL)
  641.             {
  642.                 char*                            SeparatorString;
  643.  
  644.                 SeparatorString = StringToBlockCopy(":  ");
  645.                 if (SeparatorString != NIL)
  646.                     {
  647.                         char*                            LeftHalfOfString;
  648.  
  649.                         LeftHalfOfString = ConcatBlockCopy(NewFilename,SeparatorString);
  650.                         if (LeftHalfOfString != NIL)
  651.                             {
  652.                                 char*                            TotalString;
  653.  
  654.                                 TotalString = ConcatBlockCopy(LeftHalfOfString,LocalNameCopy);
  655.                                 if (TotalString != NIL)
  656.                                     {
  657.                                         char*                            NullTerminatedString;
  658.  
  659.                                         NullTerminatedString = BlockToStringCopy(TotalString);
  660.                                         if (NullTerminatedString != NIL)
  661.                                             {
  662.                                                 SetWindowName(Window->ScreenID,NullTerminatedString);
  663.                                                 ChangeItemName(Window->MyMenuItem,NullTerminatedString);
  664.                                                 ReleasePtr(NullTerminatedString);
  665.                                             }
  666.                                         ReleasePtr(TotalString);
  667.                                     }
  668.                                 ReleasePtr(LeftHalfOfString);
  669.                             }
  670.                         ReleasePtr(SeparatorString);
  671.                     }
  672.                 ReleasePtr(LocalNameCopy);
  673.             }
  674.     }
  675.  
  676.  
  677. /* refresh the titlebar of the window */
  678. void                                FunctionWindowResetTitlebar(FunctionWindowRec* Window)
  679.     {
  680.         char*                            DocumentName;
  681.  
  682.         CheckPtrExistence(Window);
  683.         DocumentName = GetCopyOfDocumentName(Window->MainWindow);
  684.         if (DocumentName != NIL)
  685.             {
  686.                 FunctionWindowGlobalNameChange(Window,DocumentName);
  687.                 ReleasePtr(DocumentName);
  688.             }
  689.     }
  690.  
  691.  
  692. /* force the function window to write back to the object any data that has changed */
  693. MyBoolean                        FunctionWindowWritebackModifiedData(FunctionWindowRec* Window)
  694.     {
  695.         MyBoolean                    SuccessFlag = True;
  696.  
  697.         CheckPtrExistence(Window);
  698.  
  699.         /* save the name if it has been altered */
  700.         if (TextEditDoesItNeedToBeSaved(Window->NameEdit))
  701.             {
  702.                 char*                    NameTemp;
  703.  
  704.                 NameTemp = FunctionWindowGetNameCopy(Window);
  705.                 if (NameTemp != NIL)
  706.                     {
  707.                         FunctionObjectNewName(Window->FunctionObject,NameTemp);
  708.                         TextEditHasBeenSaved(Window->NameEdit);
  709.                     }
  710.                  else
  711.                     {
  712.                         SuccessFlag = False;
  713.                     }
  714.             }
  715.  
  716.         /* save the body if it has been altered */
  717.         if (TextEditDoesItNeedToBeSaved(Window->BodyEdit))
  718.             {
  719.                 char*                            Temp;
  720.  
  721.                 Temp = FunctionWindowGetSourceCopy(Window);
  722.                 if (Temp != NIL)
  723.                     {
  724.                         FunctionObjectNewSource(Window->FunctionObject,Temp);
  725.                         TextEditHasBeenSaved(Window->BodyEdit);
  726.                     }
  727.                  else
  728.                     {
  729.                         SuccessFlag = False;
  730.                     }
  731.             }
  732.  
  733.         return SuccessFlag;
  734.     }
  735.